home *** CD-ROM | disk | FTP | other *** search
- Path: natinst.com!usenet
- From: "Jonathan S. Brumley" <brumley@natinst.com>
- Newsgroups: comp.lang.c++
- Subject: Re: Virtual Constructors (how to implement)?
- Date: Fri, 16 Feb 1996 13:48:15 -0600
- Organization: National Instruments
- Message-ID: <3124DF7F.2766@natinst.com>
- References: <4g0lle$nmq@jobe.shell.portal.com>
- NNTP-Posting-Host: rosemary.natinst.com
- Mime-Version: 1.0
- Content-Type: text/plain; charset=us-ascii
- Content-Transfer-Encoding: 7bit
- X-Mailer: Mozilla 2.0 (Win95; I)
-
- Clare Chu wrote:
- >
- > I have an abstract base class Packet. Inherited from Packet
- > are specific packets like LoginPacket, AuditPacket, etc.
- >
- > What I need is to read a socket (stream), and then construct
- > the packet of the right kind, depending on what it is.
- >
- > I read a reference to this technique in Scott Meyer's More Effective C++
- > but I haven't received my copy yet. (It is back-ordered at Computer
- > Literacy).
- >
- > I need someone to basically outline what I need to do to set
- > up such a function that reads from a stream, produces the appropriate
- > object and returns a pointer to Packet pointing to the object
- > which is of the appropriate derived class.
- >
- > At present, I'm trying to implement it as an array of pointers
- > to functions. Those functions will be called based on the
- > Packet type, and create the appropriate object. Of course I
- > haven't even thought about going out of scope, destructors,
- > or such. My coworker says to just use a big switch statement
- > and construct objects based on the type.
- >
- > Any ideas?
- >
- > Thanks in advance,
- > Clare
- > clare@shell.portal.com
-
- One way to do this is to create
-
- virtual Packet* Clone() = 0;
- and
- virtual void Restore(istream& in) = 0;
-
- method in your packet class. In each of your derived classes,
- define clone() to return a new clone of the appropriate type,
- and Restore to read in the data based on the stream.
-
- e.g.
-
- Packet* LoginPacket::Clone()
- {
- return new LoginPacket();
- }
-
- void LoginPacket::Restore(istream& in)
- {
- in >> packetSize;
- // ... etc
- }
-
- At initialization time, put a prototype of each class in a table,
- so that it can be found based on type.
-
- class PacketFactory
- {
- Packet* table[number_of_types];
- ...
- };
-
- PacketFactory::PacketFactory()
- {
- table[LoginType] = new LoginPacket;
- table[AuditType] = new AuditType;
- ...
- }
-
- to read in the class,
-
- Packet* Factory::Restore(istream& in)
- {
- int type;
- in >> type;
-
- Packet* recovered = table[type]->Clone();
- recovered->Restore(in);
- }
-